package cn.com.hori.cms.ueditor.upload;

import java.io.*;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FileUtils;

import cn.com.hori.cms.ueditor.define.AppInfo;
import cn.com.hori.cms.ueditor.define.BaseState;
import cn.com.hori.cms.ueditor.define.State;


public class StorageManager {
    public static final int BUFFER_SIZE = 8192;

    private static String fileurl;

    public static String getFileurl() {
        return fileurl;
    }

    public static void setFileurl(String fileurl) {
        StorageManager.fileurl = fileurl;
    }

    public static int getBufferSize() {
        return BUFFER_SIZE;
    }

    public StorageManager() {
    }

    public static State saveBinaryFile(byte[] data, String path) {
        File file = new File(path);

        State state = valid(file);

        if (!state.isSuccess()) {
            return state;
        }

        try {
            BufferedOutputStream bos = new BufferedOutputStream(
                    new FileOutputStream(file));
            bos.write(data);
            bos.flush();
            bos.close();
        } catch (IOException ioe) {
            return new BaseState(false, AppInfo.IO_ERROR);
        }

        state = new BaseState(true, file.getAbsolutePath());
        state.putInfo("size", data.length);
        state.putInfo("title", file.getName());
        return state;
    }

    public static State saveFileByInputStream(InputStream is, String path, String picName) {
        State state = null;

        File tmpFile = getTmpFile();

        byte[] dataBuf = new byte[2048];
        BufferedInputStream bis = new BufferedInputStream(is, StorageManager.BUFFER_SIZE);

        boolean success = false;
        OutputStream outputStream = null;
        try {

            // 将目标文件生成对应的文件
            File file = new File(path);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }

            outputStream = new FileOutputStream(file);
            int byteCount;
            do {
                byteCount = is.read();
                outputStream.write(byteCount);
                outputStream.flush();
            } while (byteCount > -1);
            success = true;
        } catch (IOException e) {
            e.printStackTrace();
            return new BaseState(false, AppInfo.IO_ERROR);
        } finally {
            try {
                outputStream.close();
            } catch (IOException eio) {
                eio.printStackTrace();
            }
        }
        //如果上传成功
        if (success) {
            state = new BaseState(true);
            state.putInfo("size", tmpFile.length());
            state.putInfo("title", tmpFile.getName());
            tmpFile.delete();
        } else {
            state = new BaseState(false, 4);
            tmpFile.delete();
        }

        return state;

    }

    private static File getTmpFile() {
        File tmpDir = FileUtils.getTempDirectory();
        String tmpFileName = (Math.random() * 10000 + "").replace(".", "");
        return new File(tmpDir, tmpFileName);
    }

    private static State saveTmpFile(File tmpFile, String path) {
        State state = null;
        File targetFile = new File(path);

        if (targetFile.canWrite()) {
            return new BaseState(false, AppInfo.PERMISSION_DENIED);
        }
        try {
            FileUtils.moveFile(tmpFile, targetFile);
        } catch (IOException e) {
            return new BaseState(false, AppInfo.IO_ERROR);
        }

        state = new BaseState(true);
        state.putInfo("size", targetFile.length());
        state.putInfo("title", targetFile.getName());

        return state;
    }

    private static State valid(File file) {
        File parentPath = file.getParentFile();

        if ((!parentPath.exists()) && (!parentPath.mkdirs())) {
            return new BaseState(false, AppInfo.FAILED_CREATE_FILE);
        }

        if (!parentPath.canWrite()) {
            return new BaseState(false, AppInfo.PERMISSION_DENIED);
        }

        return new BaseState(true);
    }
}
